package dbmgr

import (
	"encoding/json"
	"time"

	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
	"golang.org/x/crypto/bcrypt"
)

type Machine struct {
	Id          int       `orm:"pk;auto;column(id);description(自增主键)"`
	Name        string    `orm:"size(100);column(name);description(机台名称)"`
	Description string    `orm:"type(text);column(description);description(设备说明)"`
	Code        string    `orm:"size(50);unique;column(code);description(唯一编号)"` // 唯一约束:ml-citation{ref="4" data="citationList"}
	CreatorId   int       `orm:"column(creator_id);description(创建人ID)"`          // int类型创建人ID
	CreatedAt   time.Time `orm:"auto_now_add;type(datetime);column(created_at);description(创建时间)"`
}

// 版本模型
type Version struct {
	Id        string    `orm:"pk;size(36);column(id);description(主键UUID)"`
	Name      string    `orm:"size(100);column(name);description(版本名称)"`
	Version   string    `orm:"size(50);column(version);description(版本号)"`
	Creator   string    `orm:"size(50);column(creator_name);not null;description(姓名)"`
	CreatorId int       `orm:"column(creator_id);description(创建人ID)"` // int类型创建人ID
	Remark    string    `orm:"type(text);null;column(remark);json(remark);description(备注信息)"`
	Machine   *Machine  `orm:"rel(fk);column(machine_id);description(关联机台)"`
	FilesMD5  string    `orm:"size(32);column(files_md5);null;description(文件合并MD5值)"` // 新增字段
	CreatedAt time.Time `orm:"auto_now_add;type(datetime);column(created_at);json(created);description(创建时间)"`
}

func (v *Version) TableUnique() [][]string {
	return [][]string{
		{"name", "version", "machine_id"}, // 联合唯一键
	}
}

func (e *Version) ToJSON() string {
	b, _ := json.Marshal(e)
	return string(b)
}

// 文件模型
type File struct {
	Id       string   `orm:"pk;size(36);description(主键UUID);column(id)"`
	FileName string   `orm:"size(255);description(文件名);column(file_name)"`
	MD5      string   `orm:"column(md5);size(32);description(文件MD5值);null;default(null)"` // 已移除 unique 标签
	Version  *Version `orm:"rel(fk);column(version_id);description(关联版本)"`
	Machine  *Machine `orm:"rel(fk);column(machine_id);description(关联版本)"`
	Path     string   `orm:"size(1024);description(文件存储路径);column(path);default(/default)"`
	IsFolder bool     `orm:"default(false);description(是否是文件夹);column(is_folder)"` // 新增字段
	ParentId string   `orm:"size(36);default(process);description(父级ID);column(parent_id)"`
	FileSize int64    `orm:"column(file_size);default(0);description(文件大小，单位字节)"`

	// 添加联合唯一约束
	UniqueConstraint string `orm:"-"`
}

func (e *File) ToJSON() string {
	b, _ := json.Marshal(e)
	return string(b)
}

// 实现接口方法（适用于beego ORM）
func (f *File) TableUnique() [][]string {
	return [][]string{
		{"file_name", "version_id", "path"}, // 联合唯一键
	}
}

// 员工模型
type Employee struct {
	ID         int    `orm:"auto;pk;column(id);description(主键UUID)"` // 自增主键
	Account    string `orm:"unique;size(50);column(account);not null;description(登录账号)"`
	Password   string `orm:"size(60);column(password);not null;description(登录密码)"`
	EmployeeId string `orm:"unique;size(20);column(employee_id);not null;description(员工工号)"`
	Phone      string `orm:"unique;size(11);column(phone);not null;description(手机号)"`
	Name       string `orm:"size(50);column(name);not null;description(姓名)"`
	Department string `orm:"size(50);column(department);not null;description(部门)"`
	Company    string `orm:"size(50);column(company);not null;description(公司名称)"`
	IsAdmin    int8   `orm:"column(is_admin);default(0);description(管理员标识 0-否 1-是)"`
	Permission string `orm:"type(text);column(permission);description(权限JSON数据)"`
}

// 创建员工时处理密码
func (e *Employee) BeforeInsert() {
	hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(e.Password), bcrypt.DefaultCost)
	e.Password = string(hashedPassword)
}

// 验证密码示例
func (e *Employee) CheckPassword(password string) bool {
	//return bcrypt.CompareHashAndPassword([]byte(e.Password), []byte(password)) == nil
	return password == e.Password
}

func (e *Employee) ToJSON() string {
	b, _ := json.Marshal(e)
	return string(b)
}

type AuthToken struct {
	Id           int       `orm:"auto;pk"`
	User         *Employee `orm:"rel(fk);column(employee_id);type(varchar(20))"`
	Token        string    `orm:"unique;size(64)"`
	CreatedAt    time.Time `orm:"auto_now_add;type(datetime)"`
	ExpiredAt    time.Time `orm:"type(datetime)"`
	LastActivity time.Time `orm:"null;type(datetime)"`
	ClientInfo   string    `orm:"size(255);null"`
	IsRevoked    bool      `orm:"default(false)"`
}

func (t *AuthToken) TableName() string {
	return "auth_tokens"
}

// 提交记录
type FileSubmission struct {
	ID               int       `orm:"pk;auto;column(id);description(自增主键)"`                 // 改为 int + auto
	VersionID        string    `orm:"size(36);column(version_id);description(关联版本ID)"`      // 外键关联Version表
	SubmissionNumber int       `orm:"unique;column(submission_number);description(提交版本编号)"` // 新增唯一编号
	Submitter        int       `orm:"column(submitter);description(提交人)"`
	SubmittedAt      time.Time `orm:"auto_now_add;type(datetime);column(submitted_at);description(提交时间)"`
	Remark           string    `orm:"type(text);null;column(remark);description(备注信息)"` // 允许为空
}

type FileSubItem struct {
	ID             int             `orm:"pk;auto;column(id);description(自增主键)"` // 改为 int + auto
	FileName       string          `orm:"size(255);column(file_name);description(原始文件名)"`
	FileSubmission *FileSubmission `orm:"rel(fk);column(file_submission_id);description(关联提交记录)"`
}

// 注册所有模型
func RegisterModels() {
	logs.Info("创建表数据")
	orm.RegisterModel(
		new(Version),
		new(File),
		new(Employee),
		new(AuthToken),
		new(FileSubmission),
		new(FileSubItem),
		new(Machine),
	)

	// 触发建表（关键步骤）
	err := orm.RunSyncdb("default", false, true)
	if err != nil {
		logs.Error("建表失败, err: %s", err.Error())
		return
	}

	logs.Info("建表成功")
}
